using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using AutoMapper;
using BaseAPI.BaseViewModel;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Debug;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Snowflake.Core;
using WebTest.Models;
using ModelError = BaseAPI.BaseViewModel.ModelError;

namespace WebTest;

public class Startup(IConfiguration configuration)
{
    private IConfiguration Configuration { get; } = configuration;

    public void ConfigureServices(IServiceCollection services)
    {
        // 不带日志
        //services.AddDbContext<DataContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultContext")));
        // 带日志
        services.AddDbContext<DataContext>(options => options.UseLoggerFactory(new LoggerFactory([
                new DebugLoggerProvider()]))
            .UseMySql(Configuration.GetConnectionString("DefaultContext"), ServerVersion.AutoDetect(Configuration.GetConnectionString("DefaultContext"))));
        // 注册Swagger生成器，定义一个或多个Swagger文档
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
            // 为 Swagger JSON 和 UI 设置路径注释
            var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath, true);
            // BaseAPI注释
            xmlPath = Path.Combine(AppContext.BaseDirectory, "BaseAPI.xml");
            c.IncludeXmlComments(xmlPath);
            c.DocumentFilter<SwaggerEnumFilter>();
        });
        // 添加MVC
        services.AddMvc(mvcOptions => mvcOptions.EnableEndpointRouting = false)
            .AddNewtonsoftJson(opt =>
            {
                // 忽略JSON解析循环引用
                opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                // 不使用驼峰样式
                //opt.SerializerSettings.ContractResolver = new DefaultContractResolver();
                // 设置时间格式
                opt.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            });
        // 自定义模型验证
        services.Configure<ApiBehaviorOptions>(options =>
        {
            options.InvalidModelStateResponseFactory = (context) =>
            {
                var modelStateList = context.ModelState.ToList();
                var modelErrorList = new List<ModelError>();
                foreach (var item in modelStateList)
                {
                    if (item.Value.ValidationState == ModelValidationState.Valid)
                        continue;
                    List<string> errors = [];
                    errors.AddRange(item.Value.Errors.Select(error => error.ErrorMessage));
                    modelErrorList.Add(new ModelError()
                    {
                        FieldName = item.Key,
                        ErrorDescriptions = errors,
                    });
                }
                return new JsonResult(ResponseModel<List<ModelError>>.ModelFailed(modelErrorList));
            };
        });
        // AutoMapper
        var config = new MapperConfiguration(cfg => { cfg.AddProfile(new AutoMapperProfile()); });
        var mapper = config.CreateMapper();
        services.AddSingleton(mapper);
        // Snowflake
        var idWorker = new IdWorker(1, 1);
        services.AddSingleton(idWorker);
        // 跨域
        services.AddCors(x => x.AddDefaultPolicy(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
        // 上传大小限制128M（默认值）
        services.Configure<FormOptions>(options => { options.MultipartBodyLengthLimit = 134217728; });
        services.Configure<KestrelServerOptions>(options => { options.Limits.MaxRequestBodySize = int.MaxValue; });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); });
            app.UseRewriter(new RewriteOptions().AddRedirect("^$", "swagger/index.html"));
        }
        //app.UseStaticFiles(new StaticFileOptions()
        //{
        //    OnPrepareResponse = c =>
        //    {
        //        c.Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        //        ServeUnknownFileTypes = true,
        //        DefaultContentType = "application/octet-stream"
        //    },
        //});
        app.UseCors();
        app.UseAuthentication();
        app.UseRouting();
        app.UseAuthorization();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}